/* Unit test for new message class */

#include "../lib/message.h"
#include "../lib/exceptions.h"

#include <iostream>
using std::cout;
using std::endl;

int main()
{   
    //Ensure exceptions are thrown
    try
    {
        //Try to create a static body message with the dynamic
        //body constructor
        Message m( Message::PublicKeyExchange );
    }
    catch( BaseException* e )
    {
        cout << "Test passed: " << e->what() << endl;
    }

    try
    {
        //Try to create a dynamic body message with a
        //body that is too long
        Message m( Message::DecryptStandard, string( 2000, 'a' ) );
    }
    catch( BaseException* e )
    {
        cout << "Test passed: " << e->what() << endl;
    }

    try
    {
        //Try to create a message from a character string
        //with a small length
        Message m( new char[10], 10 );
    }
    catch( BaseException* e )
    {
        cout << "Test passed: " << e->what() << endl;
    }

    try
    {
        //Try to create a dynamic body message with too
        //many fields
        Message m( Message::DecryptStandard );
        m.addField( "Hello" );
        m.addField( "There" );
        m.addField( "World" );
        m.toChar();
    }
    catch( BaseException* e )
    {
        cout << "Test passed: " << e->what() << endl;
    }

    //Ensure functionality is correct

    //Dynamic Body Message
    Message dbm( Message::DecryptStandard );
    dbm.addField( "Matthew" );
    dbm.addField( "Hello World!" );
    //Verify Field 1
    if( dbm[0] == "Matthew" )
        cout << "Test passed" << endl;
    else
        cout << "Test failed" << endl;
    //Verify Field 2
    if( dbm[1] == "Hello World!" )
        cout << "Test passed" << endl;
    else
        cout << "Test failed" << endl;

    //Restore a new message with char encoding
    char* encode = dbm.toChar();
    Message restore( encode, Message::MAX_SIZE );

    //Verify Field 1
    if( restore[0] == "Matthew" )
        cout << "Test passed" << endl;
    else
        cout << "Test failed" << endl;
    //Verify Field 2
    if( restore[1] == "Hello World!" )
        cout << "Test passed" << endl;
    else
        cout << "Test failed" << endl;
    
    //AES encryption test
    //Generate Key
    string key = jAes::generateKey( 32 );

    char* cipher = dbm.aesEncrypt( key ); 
    Message encrypt( cipher, Message::MAX_SIZE );

    //Verify type
    if( encrypt.getType() == Message::CryptStandard )
        cout << "Test passed" << endl;
    else
        cout << "Test failed" << endl;

    try
    {
        Message decrypt = encrypt.aesDecrypt( key );
    }
    catch( BaseException* e )
    {
        cout << "Decryption failue: " << e->what() << endl;
    }
    //Verify Field 1
    if( restore[0] == "Matthew" )
        cout << "Test passed" << endl;
    else
        cout << "Test failed" << endl;
    //Verify Field 2
    if( restore[1] == "Hello World!" )
        cout << "Test passed" << endl;
    else
        cout << "Test failed" << endl;
}
